#ifndef H_RX
#define H_RX

#include "Arduino.h"

#define MAXCHANIN 8





void change(void);
int failsafeChan[]=FAILSAFE;
unsigned long now,diff,last;
byte chan=-1; // -1 invalid


class Rx
{
private:
public:
  int ichannelIn[MAXCHANIN];
  float channelIn[MAXCHANIN];

  void failsafe()
  {
    for(byte i=0;i<MAXCHANIN;i++)
    {
      ichannelIn[i]=failsafeChan[i];
      channelIn[i]=(ichannelIn[i]-CENTER)/500.0;
    }
  }

  void setup()
  {
    failsafe();
#ifdef PPMSUM
    attachInterrupt(0,change,RISING); // TODO Bug the last channel isn't recorded
#else

#if PIPO==1
    pinMode(A0, INPUT); // 3 is used for esc
    pinMode(A1, INPUT);
    pinMode(A2, INPUT);
    pinMode(A3, INPUT);
    // interrupt on pin change PCINT
    PCICR |= (1 << PCIE1); // 8-15

    PCMSK1 = (1 << PCINT8) | // pin PC0
    (1 << PCINT9) | // pin PC1
    (1 << PCINT10) | // pin PC2
    (1 << PCINT11); // pin PC3
#else // TODO Support Teensy
    pinMode(2, INPUT); // 3 is used for esc
    pinMode(4, INPUT);
    pinMode(5, INPUT);
    pinMode(6, INPUT);
    pinMode(7, INPUT);
    // interrupt on pin change PCINT
    PCICR |= (1 << PCIE2); // 16-23

    PCMSK2 = (1 << PCINT18) | // pin2
    (1 << PCINT20) | // pin4
    (1 << PCINT21) | // pin5
    (1 << PCINT22) | // pin6
    (1 << PCINT23) ; // pin7 // not need if you don't use RXDIRECT
#endif

#endif
  }

  void update()
  {
    if (micros()-last>60000L) // 60ms without new data FAILSAFE
    {
      failsafe();
    }


    for(byte i=0;i<MAXCHANIN;i++)
      channelIn[i]=(limit(1000,ichannelIn[i],2000)-CENTER)/500.0;  // floaint point value are [-1,1]
  }
} 
rx;



void change(void)
{
  last=now;
  now=micros();
  diff=now-last;
  if (diff>2300) 
  {
    chan=0;
  }
  else if (chan!=-1 && diff>900 && diff<2200)
    rx.ichannelIn[chan++]=diff;
  else  
    chan=-1; // invalid

}


///////////////////////////// ISR
#if !defined(PPMSUM)
#if PIPO==1

#define MASKPCINT0 (1<<0)
#define MASKPCINT1 (1<<1)
#define MASKPCINT2 (1<<2)
#define MASKPCINT3 (1<<3)

ISR(PCINT1_vect)

#else

#define MASKPCINT0 (1<<2)
#define MASKPCINT1 (1<<4)
#define MASKPCINT2 (1<<5)
#define MASKPCINT3 (1<<6)
#define MASKPCINT4 (1<<7)
ISR(PCINT2_vect)

#endif


{
  static byte newbit,oldbit,changed;
  static unsigned long startIn[5];
  last=now;
  now=micros(); 

#if PIPO==1
  newbit=PINC;
#else
  newbit=PIND;
#endif

  // This is a new VERY VERY VERY fast method 
  // 1 xor operation 

  changed=newbit^oldbit;

  if (changed&MASKPCINT0)
    if (newbit&MASKPCINT0) startIn[0]=now;
    else rx.ichannelIn[0]=now-startIn[0];

  if (changed&MASKPCINT1)
    if (newbit&MASKPCINT1) startIn[1]=now;
    else rx.ichannelIn[1]=now-startIn[1];

  if (changed&MASKPCINT2)
    if (newbit&MASKPCINT2) startIn[2]=now;
    else rx.ichannelIn[2]=now-startIn[2];

#ifdef MASKPCINT3
  if (changed&MASKPCINT3)
    if (newbit&MASKPCINT3) startIn[3]=now;
    else rx.ichannelIn[3]=now-startIn[3];
#endif

#ifdef MASKPCINT4
  if (changed&MASKPCINT4)
    if (newbit&MASKPCINT4) startIn[4]=now;
    else rx.ichannelIn[4]=now-startIn[4];
#endif

  oldbit=newbit;

}

#endif

#endif

















